home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software Vault: The Diamond Collection
/
The Diamond Collection (Software Vault)(Digital Impact).ISO
/
cdr44
/
xlib06p1.zip
/
XMOUSE.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1995-03-15
|
9KB
|
360 lines
#include "xinternl.h"
#include <i86.h>
#include <mem.h>
#include <conio.h>
/*==================================================================
XMOUSE.CPP contains the basic setup variables and functions for the
XLIB mouse handler.
These routines were written initially by Themie Gouthas and
company and modified March 1995 by Victor B. Putz.
===================================================================*/
int MouseInstalled; /* Indicates whether mouse handler installed */
int MouseHidden; /* Indicates whether mouse cursor is hidden */
int MouseButtonStatus;/* Holds the mouse button status */
int MouseX; /* Current X position of mouse cursor */
int MouseY; /* Current Y position of mouse cursor */
BYTE MouseFrozen; /* Disallows position updates if TRUE */
xColor_t MouseColor; /* The mouse cursors colour */
BYTE InitMouseDef[] = {
0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff,
0x1f, 0x1b, 0x31, 0x30, 0x60, 0x60
};
BYTE MouseMask[ 168 ];
BYTE * pbOldHandler = NULL;
int OldX = 0;
int OldY = 0;
int OldScrnOffs = 0;
int BGSaveOffs = 0;
static void _loadds far MouseHandler( int, int, int, int );
BYTE InHandler = 0;
int MouseButtonCount = 0;
extern BYTE * pbVGABuffer;
extern int NonVisual_Offs;
extern int VisiblePageOffs;
extern int ScrnLogicalPixelWidth;
extern int ScrnLogicalByteWidth;
extern int ScrnPhysicalPixelWidth;
extern int ScrnPhysicalHeight;
extern int ScrnLogicalHeight;
void x_define_mouse_cursor( /* Define and set a cursor shape */
char * MouseDef,
xColor_t color
)
{
if ( !MouseInstalled ) {
return;
}
MouseColor = color;
//now set up storage for all pixel alignments of mouse cursor
BYTE * pbSource = ( BYTE * )MouseDef;
BYTE * pbDest = MouseMask;
//loop for each pixel alignment ( i = alignment )
for( int iAlignment = 0; iAlignment < 4; ++iAlignment ) {
pbSource = (BYTE *)MouseDef;
for( int iRowLoop = 0; iRowLoop < 14; ++iRowLoop ) {
int iTemp = *pbSource++;
iTemp <<= iAlignment;
*pbDest++ = ( BYTE )( iTemp & 0x0f );
*pbDest++ = ( BYTE )(( iTemp >> 4 ) & 0x0f);
*pbDest++ = ( BYTE )(( iTemp >> 8 ) & 0x0f);
}
}
}
void x_mouse_init(
void
)
{
union REGPACK regs;
memset( ®s, 0, sizeof( regs ) );
if ( MouseButtonCount == 0 ) {
//set up ax with mouse initialization command
regs.w.ax = 0;
intr( 0x33, ®s ); //mouse interrupt
int iIsMouse = regs.w.ax;
if ( iIsMouse ) {
MouseButtonCount = regs.w.bx;
}
}
MouseInstalled = regs.w.ax;
if ( !MouseInstalled ) {
return;
}
//update memory positions to make space to save the mouse backgnd
BGSaveOffs = NonVisual_Offs;
NonVisual_Offs += 14*3;
//hide cursor
regs.w.ax = 0x02;
intr( 0x33, ®s );
MouseInstalled = TRUE;
//set min/max horizontal position
regs.w.ax = 0x07;
regs.w.cx = 0;
//multiply right edge by 2 since cursor steps by 2 pixels...
regs.w.dx = ( WORD )( ScrnPhysicalPixelWidth * 2 );
intr( 0x33, ®s );
//set min/max vertical position
regs.w.ax = 0x08;
regs.w.cx = 0;
regs.w.dx = ( WORD )ScrnPhysicalHeight;
intr( 0x33, ®s );
//get mouse position and button status
regs.w.ax = 0x03;
intr( 0x33, ®s );
MouseY = regs.w.dx;
MouseX = regs.w.cx;
//now define our event handler ( this is where it gets edgy )
regs.w.ax = 0x0c;
regs.w.cx = 0x1f; //since we handle all events
regs.x.edx = FP_OFF( &MouseHandler );
regs.w.es = FP_SEG( &MouseHandler );
intr( 0x33, ®s );
//set up initial mouse state
MouseHidden = TRUE;
x_define_mouse_cursor( ( char * )InitMouseDef, regs.x.ds );
}
/*
RestoreBg() restores the stored cursor background
*/
void RestoreBg(
xPageHandle_t iOffset,
xScreenCoord_t iX,
xScreenCoord_t iY
)
{
BYTE * pbDest = pbVGABuffer + ( iY * ScrnLogicalByteWidth ) + iX / 4 + iOffset;
BYTE * pbSource = pbVGABuffer + BGSaveOffs;
int iSkip = ScrnLogicalByteWidth - 3;
outpw( GC_INDEX, BIT_MASK );
outp( SC_INDEX, MAP_MASK );
outp( SC_INDEX + 1, 0x0f );
for ( int i = 14; i != 0; --i ) {
//copy the data
*pbDest++ = *pbSource++;
*pbDest++ = *pbSource++;
*pbDest++ = *pbSource++;
pbDest += iSkip;
}
outp( GC_INDEX + 1, 0x0ff );
}
/*
GetBg() gets the background and stores it to the saved area.
*/
void GetBg(
xPageHandle_t iOffset,
xScreenCoord_t iX,
xScreenCoord_t iY
)
{
BYTE * pbSource = pbVGABuffer + ( iY * ScrnLogicalByteWidth ) + iX / 4 + iOffset;
BYTE * pbDest = pbVGABuffer + BGSaveOffs;
int iSkip = ScrnLogicalByteWidth - 3;
outpw( GC_INDEX, BIT_MASK );
outp( SC_INDEX, MAP_MASK );
outp( SC_INDEX + 1, 0x0f );
for ( int i = 14; i != 0; --i ) {
//copy the data
*pbDest++ = *pbSource++;
*pbDest++ = *pbSource++;
*pbDest++ = *pbSource++;
pbSource += iSkip;
}
outp( GC_INDEX + 1, 0x0ff );
}
void x_hide_mouse(
void
)
{
if ( !MouseInstalled || MouseHidden ) {
return;
}
while( InHandler ) {
NULL;
}
MouseHidden = TRUE;
RestoreBg( OldScrnOffs, OldX, OldY );
}
void x_mouse_remove(
void
)
{
if ( !MouseInstalled ) {
return;
}
union REGPACK regs;
memset( ®s, 0, sizeof( regs ) );
regs.w.ax = 12; //install event handler
regs.w.cx = 0; //disable all events
intr( 0x33, ®s );
}
void x_position_mouse( /* Set the mouse position */
xScreenCoord_t x,
xScreenCoord_t y);
void x_put_cursor( /* Draw the mouse cursor (NOT FOR */
xScreenCoord_t iX, /* general use) */
xScreenCoord_t iY,
xScreenCoord_t iTopClip,
xScreenCoord_t iBotClip,
xPageHandle_t ScrnOff
)
{
int iLinesToDisplay = 14;
int iTemp = iTopClip - iY;
int iStartY = iY;
int iStartSourceY = 0;
//check top clipping
if ( iTemp > 0 ) {
if ( iTemp > iLinesToDisplay ) {
return;
}
else {
iLinesToDisplay -= iTemp;
iStartSourceY = iTemp;
iStartY = iTopClip;
}
}
//check bottom clipping
iTemp = iStartY + iLinesToDisplay - iBotClip;
if ( iTemp > 0 ) {
iLinesToDisplay -= iTemp;
}
if ( iLinesToDisplay < 0 ) {
return;
}
//now draw this fella
BYTE * pbDest = pbVGABuffer + ScrnOff + ( iStartY * ScrnLogicalByteWidth ) + iX / 4;
int iSkip = ScrnLogicalByteWidth - 3;
BYTE * pbSource = MouseMask + ( 42 * ( iX & 3 ) ) + iStartSourceY * 3;
outp( SC_INDEX, MAP_MASK );
while ( iLinesToDisplay-- ) {
for ( int i = 3; i != 0; --i ) {
outp( SC_INDEX + 1, *pbSource++ );
*pbDest++ = ( BYTE )MouseColor;
}
pbDest += iSkip;
}
}
void x_show_mouse(
void
)
{
if ( !MouseInstalled || !MouseHidden ) {
return;
}
while ( InHandler ) {
NULL;
}
MouseHidden = FALSE;
OldScrnOffs = VisiblePageOffs;
OldX = MouseX;
OldY = MouseY;
GetBg( OldScrnOffs, OldX, OldY );
x_put_cursor( OldX, OldY, 0, ScrnLogicalHeight, VisiblePageOffs );
}
void x_mouse_window(
xScreenCoord_t x0, /* Define a mouse window */
xScreenCoord_t y0,
xScreenCoord_t x1,
xScreenCoord_t y1);
/*
UpdateCursor() updates the cursor position
*/
void UpdateCursor(
void
)
{
RestoreBg( OldScrnOffs, OldX, OldY );
OldScrnOffs = VisiblePageOffs;
OldX = MouseX;
OldY = MouseY;
GetBg( VisiblePageOffs, MouseX, MouseY );
x_put_cursor( MouseX, MouseY, 0, ScrnPhysicalHeight, VisiblePageOffs );
}
void x_update_mouse(
void
)
{
if ( !MouseInstalled || MouseHidden ) {
return;
}
union REGPACK regs;
memset( ®s, 0, sizeof( regs ) );
regs.w.ax = 0x03;
intr( 0x33, ®s );
MouseY = regs.w.dx;
MouseX = regs.w.cx;
MouseButtonStatus = regs.w.bx;
UpdateCursor();
}
void far * GetStack( void );
void SetStack( void far * );
#pragma aux GetStack = "mov dx,ss" \
"mov eax,esp" value [ dx eax ];
#pragma aux SetStack = "mov ss,dx" \
"mov esp,eax" parm [ dx eax ];
#pragma aux MouseHandler parm [ ecx ] [ edx ] [ ebx ] [ eax ]
#define STACKSIZE 1024
static void _loadds far MouseHandler(
int iX,
int iY,
int iButtonStatus,
int iMotionEvent
)
{
if ( InHandler ) {
return;
}
static char newstack[ STACKSIZE ];
static void far *oldstack;
InHandler = 1;
MouseButtonStatus = iButtonStatus;
if ( iMotionEvent & 1 ) {
MouseX = iX / 2;
MouseY = iY;
if ( ( !MouseHidden ) && ( !MouseFrozen ) ) {
oldstack = GetStack();
SetStack( newstack + STACKSIZE );
UpdateCursor();
SetStack( oldstack );
}
}
InHandler = 0;
}